package org.softmed.rest.server.core.http;

import java.util.List;

import org.restlet.data.Status;
import org.softmed.rest.config.HttpMethod;
import org.softmed.rest.config.MimeTypeHandler;
import org.softmed.rest.server.core.handler.HandlerProcessParameters;
import org.softmed.rest.server.core.handler.HandlerProcessor;

public abstract class AbstractCommonSpecificHttpMethodProcessor implements
		SpecificHttpMethodProcessor, Cloneable {

	protected HandlerProcessParameters parameters;

	@Override
	public void process(HttpMethod requestHttpMethod,
			HandlerProcessor instanceHandlerSolver,
			HandlerProcessParameters parameters) throws Throwable {

		this.parameters = parameters;

		preProcessHttpMethod(requestHttpMethod, instanceHandlerSolver,
				parameters);

		instanceHandlerSolver.solve(requestHttpMethod.getHandler(), parameters);

		postProcessHttpMethod(requestHttpMethod, instanceHandlerSolver,
				parameters);

		if (!instanceHandlerSolver.isContinueProcessing()) {
			stopProcessingAfterHttpHandler();
			return;
		}

		if (isProcessMimeTypeHandler())
			processMediaTypeHandlers(requestHttpMethod, instanceHandlerSolver,
					parameters);

		// todo select a proper mime type handler

		// depends on wether or not it continues to process and if mime type
		// processing is required

		// TODO

	}

	protected abstract void stopProcessingAfterHttpHandler();

	protected void processMediaTypeHandlers(HttpMethod requestHttpMethod,
			HandlerProcessor instanceHandlerSolver,
			HandlerProcessParameters parameters) throws Throwable {
		List<MimeTypeHandler> mimeHandlers = requestHttpMethod
				.getMimeTypeHandlers();
		MimeTypeHandler selectedMimeTypeHandler = null;
		String mimeType = null;
		String targetMimeType = getMimeTypeToProcess();
		for (MimeTypeHandler mimeTypeHandler : mimeHandlers) {
			if (!mimeTypeHandler.isActive())
				continue;
			mimeType = mimeTypeHandler.getMimeType();
			if (mimeType.equalsIgnoreCase(targetMimeType)) {
				selectedMimeTypeHandler = mimeTypeHandler;
				break;
			}
		}

		if (selectedMimeTypeHandler == null) {
			parameters.getResponse().setStatus(
					Status.SERVER_ERROR_NOT_IMPLEMENTED);
			return;
		}

		preProcessMimeType(selectedMimeTypeHandler, requestHttpMethod,
				instanceHandlerSolver, parameters);
		// process mediaType Handler
		parameters.setMimeTypeHandler(selectedMimeTypeHandler);
		instanceHandlerSolver.solve(selectedMimeTypeHandler.getHandler(),
				parameters);

		postProcessMimeType(selectedMimeTypeHandler, requestHttpMethod,
				instanceHandlerSolver, parameters);

	}

	protected abstract void postProcessHttpMethod(HttpMethod requestHttpMethod,
			HandlerProcessor instanceHandlerSolver,
			HandlerProcessParameters parameters);

	protected abstract void preProcessHttpMethod(HttpMethod requestHttpMethod,
			HandlerProcessor instanceHandlerSolver,
			HandlerProcessParameters parameters);

	protected abstract void postProcessMimeType(
			MimeTypeHandler selectedMimeTypeHandler,
			HttpMethod requestHttpMethod,
			HandlerProcessor instanceHandlerSolver,
			HandlerProcessParameters parameters);

	protected abstract void preProcessMimeType(
			MimeTypeHandler selectedMimeTypeHandler,
			HttpMethod requestHttpMethod,
			HandlerProcessor instanceHandlerSolver,
			HandlerProcessParameters parameters);

	protected abstract boolean isProcessMimeTypeHandler();

	protected abstract String getMimeTypeToProcess();

	public abstract AbstractCommonSpecificHttpMethodProcessor clone();

}
